<template>
  <div class='login-panel'>
    <el-form class="form" :model="formData" status-icon ref="formRef" :rules="rules">
      <div class="form-title"><span>sign in to your</span></div>
      <div class="title-2"><span>SPACE</span></div>
      <el-form-item class="input-container" prop="username">
        <el-input v-model="formData.username" class="input-mail" type="name" placeholder="Enter username" />
        <span> </span>
      </el-form-item>
      <section class="bg-stars">
        <span class="star"></span>
        <span class="star"></span>
        <span class="star"></span>
        <span class="star"></span>
      </section>

      <el-form-item class="input-container" prop="password">
        <el-input class="input-pwd" type="password" placeholder="Enter password" v-model="formData.password" />
      </el-form-item>
      <el-button type="primary" class="submit" @click="loginHandler" style="display: flex; justify-content: center;">
        <span class="sign-text">Sign in</span>
      </el-button>
    </el-form>
  </div>
</template>

<script lang='ts'>
export default {
  name: 'vue',
}
</script>

<script lang='ts' setup>
import { apiLogin, type IUserLoginInfo } from '@/service/utils';
import { ElMessage, type ElForm, type FormRules } from 'element-plus';
import { reactive, ref } from 'vue';
import { useRoute, useRouter, type LocationQuery } from 'vue-router';



const router = useRouter()
const route = useRoute()
//控制是否记住密码的响应式变量，默认false不记住
const isRemPwd = ref(false);
//用户名和密码
const formData: IUserLoginInfo = reactive({
  username: 'admin',
  password: '123456',
})


//创建一个响应式对象来定义正则校验输入框的内容
const rules = reactive<FormRules>({
  username: [
    { required: true, message: '请输入账号', trigger: 'change' }, //trigger: 'blur':失去焦点时触发
    { pattern: /^[A-Za-z0-9]{5,20}$/, message: '账号长度在5到20个字符', trigger: 'change' },//trigger: 'change':内容发生改变时触发
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'change' },
    { pattern: /^[A-Za-z0-9]{6,20}$/, message: '密码长度在6到20个字符', trigger: 'change' }
  ]
})

//执行帐号的登录逻辑,只有符合正则规则的才能登录成功
const formRef = ref<InstanceType<typeof ElForm>>();
//执行登录
const loginHandler = async () => {
  formRef.value?.validate(async (valid) => {
    if (valid) {
      try {
        //调用apiLogin方法，传入formData参数，获取返回数据
        const resData = await apiLogin(formData)

        //打印返回数据
        console.log(resData.data)
        //判断返回数据的状态码是否为2000，且data是否存在
        if (resData.code !== '2000' || !resData.data) {
          //抛出错误，错误信息为返回数据的msg，若msg不存在，则抛出未知错误
          throw new Error(resData.msg || '未知错误')
        }
        //登录成功
        //将返回数据的data存入localStorage中，键名为token
        localStorage.setItem('token', resData.data)
        //延时12毫秒后，跳转到指定路径
        setTimeout(() => {
          const { path, queryParams } = parseRedirect()
          router.push({ path: path, query: queryParams })
        }, 12)
      } catch (e: unknown) {
        //捕获错误
        if (e instanceof Error) {
          //若错误为Error类型，则弹出错误信息
          alert(e.message)
        } else {
          //若错误为非Error类型，则弹出未知错误
          alert('未知错误') //对于非Error类型的处理
        }
      }
    } else {
      //表单验证失败
      alert('请输入正确的账号和密码')
    }
  })
}

/*解析 redirect字符串为path和queryParams */
function parseRedirect(): { path: string; queryParams: Record<string, string> } {
  //从 vue-router 提供的 route.query 中提取查询参数
  const query: LocationQuery = route.query
  console.log(query)

  //尝试从 query 中获取名为 redirect 的参数值   如果 redirect 不存在或是 null/undefined，则使用 '/' 作为默认值
  const redirect = (query.redirect as string) ?? '/'
  console.log(redirect)

  //创建一个 URL 对象，用于解析 redirect    1、redirect：是目标路径或 URL   2、window.location.origin：是当前网页的域名部分
  const url = new URL(redirect, window.location.origin)
  console.log(url)

  //作用：从 URL 对象中获取路径部分（例如 /dashboard）
  const path = url.pathname
  console.log(path)

  //创建一个空对象，用于存储 URL 中的查询参
  const queryParams: Record<string, string> = {}
  console.log(queryParams)

  //遍历 URL 对象的查询参数（searchParams）。将每个参数的键值对存储到 queryParams 对象中。
  console.log(url.searchParams)

  url.searchParams.forEach((value, key) => {
    queryParams[key] = value
  })

  return { path, queryParams }
}
</script>

<style lang='scss'>
/* From Uiverse.io by John-CFO */
.form {
  position: relative;
  display: block;
  padding: 2.2rem;
  max-width: 350px;
  background: linear-gradient(14deg, rgba(2, 0, 36, 0.8) 0%, rgba(24, 24, 65, 0.7) 66%,
      rgb(20, 76, 99) 100%), radial-gradient(circle, rgba(2, 0, 36, 0.5) 0%,
      rgba(32, 15, 53, 0.2) 65%, rgba(14, 29, 28, 0.9) 100%);
  border: 2px solid #fff;
  -webkit-box-shadow: rgba(0, 212, 255) 0px 0px 50px -15px;
  box-shadow: rgba(0, 212, 255) 0px 0px 50px -15px;
  overflow: hidden;
  z-index: +1;
}

/*------input and submit section-------*/

.input-container {
  position: relative;
}

.input-container input,
.form button {
  outline: none;
  border: 2px solid #ffffff;
  margin: 8px 0;
  font-family: monospace;
}

.input-container input {
  background-color: #fff;
  padding: 6px;
  font-size: 0.875rem;
  line-height: 1.25rem;
  width: 250px;
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}

.input-mail:focus::placeholder {
  opacity: 0;
  transition: opacity .9s;
}

.input-pwd:focus::placeholder {
  opacity: 0;
  transition: opacity .9s;
}

/* From Uiverse.io by barisdogansutcu */
.submit {
  border: none;
  position: relative;
  width: 200px;
  height: 73px;
  padding: 0;
  z-index: 2;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='868' width='2500' viewBox='0 0 726 252.17'%3E%3Cpath d='M483.92 0S481.38 24.71 466 40.11c-11.74 11.74-24.09 12.66-40.26 15.07-9.42 1.41-29.7 3.77-34.81-.79-2.37-2.11-3-21-3.22-27.62-.21-6.92-1.36-16.52-2.82-18-.75 3.06-2.49 11.53-3.09 13.61S378.49 34.3 378 36a85.13 85.13 0 0 0-30.09 0c-.46-1.67-3.17-11.48-3.77-13.56s-2.34-10.55-3.09-13.61c-1.45 1.45-2.61 11.05-2.82 18-.21 6.67-.84 25.51-3.22 27.62-5.11 4.56-25.38 2.2-34.8.79-16.16-2.47-28.51-3.39-40.21-15.13C244.57 24.71 242 0 242 0H0s69.52 22.74 97.52 68.59c16.56 27.11 14.14 58.49 9.92 74.73C170 140 221.46 140 273 158.57c69.23 24.93 83.2 76.19 90 93.6 6.77-17.41 20.75-68.67 90-93.6 51.54-18.56 103-18.59 165.56-15.25-4.21-16.24-6.63-47.62 9.93-74.73C656.43 22.74 726 0 726 0z'/%3E%3C/svg%3E") no-repeat 50% 50%;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='868' width='2500' viewBox='0 0 726 252.17'%3E%3Cpath d='M483.92 0S481.38 24.71 466 40.11c-11.74 11.74-24.09 12.66-40.26 15.07-9.42 1.41-29.7 3.77-34.81-.79-2.37-2.11-3-21-3.22-27.62-.21-6.92-1.36-16.52-2.82-18-.75 3.06-2.49 11.53-3.09 13.61S378.49 34.3 378 36a85.13 85.13 0 0 0-30.09 0c-.46-1.67-3.17-11.48-3.77-13.56s-2.34-10.55-3.09-13.61c-1.45 1.45-2.61 11.05-2.82 18-.21 6.67-.84 25.51-3.22 27.62-5.11 4.56-25.38 2.2-34.8.79-16.16-2.47-28.51-3.39-40.21-15.13C244.57 24.71 242 0 242 0H0s69.52 22.74 97.52 68.59c16.56 27.11 14.14 58.49 9.92 74.73C170 140 221.46 140 273 158.57c69.23 24.93 83.2 76.19 90 93.6 6.77-17.41 20.75-68.67 90-93.6 51.54-18.56 103-18.59 165.56-15.25-4.21-16.24-6.63-47.62 9.93-74.73C656.43 22.74 726 0 726 0z'/%3E%3C/svg%3E") no-repeat 50% 50%;
  -webkit-mask-size: 100%;
  cursor: pointer;
  background-color: transparent;
  transform: translateY(8px);
  left: 30px
}

.submit:after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  box-shadow: 0px 0 0 0 white;
  transition: all 2s ease;
}

.submit:hover:after {
  box-shadow: 0px -13px 56px 12px #ffffffa6;
}

.submit span {
  position: absolute;
  width: 100%;
  font-size: 15px;
  font-weight: 100;
  left: 50%;
  top: 39%;
  letter-spacing: 3px;
  text-align: center;
  transform: translate(-50%, -50%);
  color: black;
  transition: all 2s ease;
}

.submit:hover span {
  color: white;
}

.submit:before {
  content: '';
  position: absolute;
  width: 0;
  height: 100%;
  background-color: black;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  transition: all 1s ease;
}

.submit:hover:before {
  width: 100%;
}



/*--------signup section---------*/

.signup-link {
  color: #c0c0c0;
  font-size: 0.875rem;
  line-height: 1.25rem;
  text-align: center;
  font-family: monospace;
}

.signup-link a {
  color: #fff;
  text-decoration: none;
}

.up:hover {
  text-decoration: underline;
}


/*--------header section-----------*/

.form-title {
  font-size: 1.25rem;
  line-height: 1.75rem;
  font-family: monospace;
  font-weight: 600;
  text-align: center;
  color: #fff;
  text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
  animation-duration: 1.5s;
  overflow: hidden;
  transition: .12s;
}

.form-title span {
  animation: flickering 2s linear infinite both;
}

.title-2 {
  display: block;
  margin-top: -0.5rem;
  font-size: 2.1rem;
  font-weight: 800;
  font-family: Arial, Helvetica, sans-serif;
  text-align: center;
  -webkit-text-stroke: #fff 0.1rem;
  letter-spacing: 0.2rem;
  color: transparent;
  position: relative;
  text-shadow: 0px 0px 16px #CECECE;
}

.title-2 span::before,
.title-2 span::after {
  content: '—';
}

@keyframes flickering {

  0%,
  100% {
    opacity: 1;
  }

  41.99% {
    opacity: 1;
  }

  42% {
    opacity: 0;
  }

  43% {
    opacity: 0;
  }

  43.01% {
    opacity: 1;
  }

  47.99% {
    opacity: 1;
  }

  48% {
    opacity: 0;
  }

  49% {
    opacity: 0;
  }

  49.01% {
    opacity: 1;
  }
}

/*---------shooting stars-----------*/


.bg-stars {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -2;
  background-size: cover;
  animation: animateBg 50s linear infinite;
}

@keyframes animateBg {

  0%,
  100% {
    transform: scale(1);
  }

  50% {
    transform: scale(1.2);
  }
}

.star {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 4px;
  height: 4px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.1), 0 0 0 8px rgba(255, 255, 255, 0.1), 0 0 20px rgba(255, 255, 255, 0.1);
  animation: animate 3s linear infinite;
}

.star::before {
  content: '';
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 300px;
  height: 1px;
  background: linear-gradient(90deg, #fff, transparent);
}

@keyframes animate {
  0% {
    transform: rotate(315deg) translateX(0);
    opacity: 1;
  }

  70% {
    opacity: 1;
  }

  100% {
    transform: rotate(315deg) translateX(-1000px);
    opacity: 0;
  }
}

.star:nth-child(1) {
  top: 0;
  right: 0;
  left: initial;
  animation-delay: 0s;
  animation-duration: 1s;
}

.star:nth-child(2) {
  top: 0;
  right: 100px;
  left: initial;
  animation-delay: 0.2s;
  animation-duration: 3s;
}

.star:nth-child(3) {
  top: 0;
  right: 220px;
  left: initial;
  animation-delay: 2.75s;
  animation-duration: 2.75s;
}

.star:nth-child(4) {
  top: 0;
  right: -220px;
  left: initial;
  animation-delay: 1.6s;
  animation-duration: 1.6s;
}
</style>
